<!--
 * @Author: 赵宇
 * @Description: 
 * @Date: 2023-03-03 14:11:11
 * @LastEditTime: 2023-03-03 14:24:36
 * @LastEditors: zhao 13370229059@163.com
 * @FilePath: \pcj\src\page\product\components\calculator.vue
-->
<template>
  <div class="num">
    <el-button size="mini" plain type="primary" v-for="item in custom" :key="item.id" @click="onTagChange(item)">
      {{ item.label }}
    </el-button>
    <ul class="num-content">
      <li class="num-content-show">
        {{ params.numActiveData.join('') }}
      </li>
      <li class="num-content-calculator">
        <div v-for="(item, index) in numData" :key="index" class="dis-flex w-100">
          <div
            v-for="row in item"
            :key="row.label"
            class="num-content-calculator-button"
            :style="{ width: row.width || '40px', flex: row.width ? 2 : 1, borderRadius: row.width ? '20px' : '50%' }"
            @click="onCalculatorChange(row)"
          >
            {{ row.text }}
          </div>
        </div>
      </li>
    </ul>
    <el-button type="primary" @click="check(true)" class="mt-20" size="mini" icon="el-icon-s-check">验证</el-button>
    <el-button type="danger" @click="close" class="mt-20" size="mini" icon="el-icon-circle-close">清空</el-button>
  </div>
</template>

<script setup>
let $message = inject('$message');

let numData = [
  [
    { text: '(', val: '' },
    { text: ')', val: '' },
    { text: '←', val: '', width: '80px' }
  ],
  [
    { text: '1', val: '' },
    { text: '2', val: '' },
    { text: '3', val: '' },
    { text: '+', val: '' }
  ],
  [
    { text: '4', val: '' },
    { text: '5', val: '' },
    { text: '6', val: '' },
    { text: '-', val: '' }
  ],
  [
    { text: '7', val: '' },
    { text: '8', val: '' },
    { text: '9', val: '' },
    { text: '*', val: '' }
  ],
  [
    { text: '0', val: '', width: '80px' },
    { text: '.', val: '' },
    { text: '/', val: '' }
  ]
];
let params = reactive({
  numActiveData: [],
  valActiveData: []
});
let props = defineProps({
  custom: {
    type: Array,
    default: () => {
      return [];
    }
  },
  data: {
    type: Object,
    default: () => {
      return {};
    }
  }
});
watch(
  () => props.data,
  val => {
    params.numActiveData = val.formulaName ? JSON.parse(val.formulaName) : [];
    params.valActiveData = val.formulaLabel ? JSON.parse(val.formulaLabel) : [];
  },
  {
    immediate: true
  }
);
const onTagChange = val => {
  params.numActiveData.push(val.label);
  params.valActiveData.push(val.attributeName);
};
const onCalculatorChange = val => {
  if (val.text === '←') {
    params.numActiveData.splice(params.numActiveData.length - 1, 1);
    params.valActiveData.splice(params.valActiveData.length - 1, 1);
    return;
  }
  params.numActiveData.push(val.text);
  params.valActiveData.push(val.text);
};
const getRandomNum = (min, max) => {
  return min + Math.round((max - min) * Math.random());
};
const close = () => {
  params.numActiveData = [];
  params.valActiveData = [];
};
// 验证判断 val 控制 是否显示验证成功提示
const check = (val = false) => {
  let arr = params.numActiveData;
  if (!arr.length) {
    $message('计算公式为空！');
    return;
  }
  let calArr = params.numData.reduce((t, r) => {
    t.push(...r.map(n => n.text));
    return t;
  }, []);
  try {
    let replaceArr = [];
    arr.map(r => {
      if (calArr.find(n => n === r)) {
        replaceArr.push(r);
        return;
      }
      replaceArr.push(getRandomNum(1, 9999999));
    });
    let res = eval(replaceArr.join(''));
    // 结果为无穷数也会验证失败
    if (res === Infinity) {
      $message('验证失败，请仔细检查');
      return;
    }
    let type = false;
    arr.map((r, i) => {
      if (type) return;
      if (calArr.find(n => n === r)) return;
      type = arr[i + 1] ? !['(', ')', '+', '-', '*', '/'].includes(arr[i + 1]) : false;
      if (type) {
        $message(`${r} 后面 ${arr[i + 1]} 有误`);
        return;
      }
      type = arr[i - 1] ? !['(', ')', '+', '-', '*', '/'].includes(arr[i - 1]) : false;
      if (type) {
        $message(`${r} 前面 ${arr[i - 1]} 有误`);
      }
    });
    if (type) return;
    if (val) $message('验证');
    return true;
  } catch (_) {
    $message('验证失败，请仔细检查');
  }
};
</script>

<style lang="scss" scoped>
.num {
  width: 100%;
}
.num-content {
  display: flex;
  margin-top: 5px;
  &-show {
    background-color: #f4f4f5;
    color: #bcbec2;
    padding: 5px;
    margin: 5px;
    flex: 1;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    letter-spacing: 2px;
    line-height: 1.5;
  }
  &-calculator {
    width: 180px;
    &-button {
      color: #fff;
      text-align: center;
      border-radius: 50%;
      position: relative;
      background-color: #a9c7da;
      height: 40px;
      line-height: 40px;
      margin-top: 5px;
      margin-left: 5px;
      transition: all 0.4s cubic-bezier(0.85, 0.05, 0.18, 1.35);
      user-select: none;
      box-shadow: 0px -6px 10px white, 0px 4px 15px rgb(0 0 0 / 15%);
      &:hover {
        opacity: 0.8;
        cursor: pointer;
      }
      &:active {
        box-shadow: 0 15px 20px rgb(0 0 0 / 2%);
      }
    }
  }
}
</style>
